import type { IMenu } from '@apps/_share/store/menu'
import type { App } from 'vue'
import type { Router, RouteRecordRaw } from 'vue-router'
import { UseModuleType } from '@apps/_share/enums'
import {
  createPageTitleGuard,
  createPermissionGuard,
  createProgressGuard,
  createRouteMapGuard,
} from '@apps/_share/route-guards'
import useMicroStore from '@apps/_share/store/micro'
import { isFrontendLoadRoute } from '@apps/_share/utils'
import { createRouter, createWebHistory } from 'vue-router'
import { RoutePath } from '../enums/route'
import { APP_CODE, LOAD_ROUTE_TYPE } from '../settings'

const frontendRoutes: RouteRecordRaw[] = Object
  .values(import.meta.glob('../routes/*.ts', { eager: true }))
  .map((route: any) => route.default)
  .flat()

export const router = createRouter({
  history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
  routes: [
    ...(
      isFrontendLoadRoute(LOAD_ROUTE_TYPE)
        ? [
            ...frontendRoutes,
            {
              path: '/:pathMatch(.*)*',
              name: '404',
              component: () => import('@apps/_share/pages/404/index.vue'),
            },
          ]
        : []
    ),
    {
      path: '/',
      redirect: RoutePath.home,
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('@apps/_share/pages/login/index.vue'),
    },
  ],
})

function createGuards(router: Router) {
  createPermissionGuard({
    router,
    loadRouteType: LOAD_ROUTE_TYPE,
    appCode: APP_CODE,
    getComponent: (menu: IMenu) => {
      return frontendRoutes.find(route => route.path === menu.path)?.component
    },
  })

  const microStore = useMicroStore()
  if (microStore.getIsMicro) {
    createProgressGuard(router)
  }

  createRouteMapGuard(router, {})
  createPageTitleGuard(router)
}

export function install(app: App) {
  createGuards(router)
  app.use(router)
}

export const moduleType = UseModuleType.ROUTER
